/* Copyright 2010 Justin Jia
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * 
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** 
 * @file BasicCFG.cc
 * @brief This file demostrates the usage of CFG parser as well as makes up a integrated test.
 * @author Justin Jia
 * @version 0.1
 * @date 2010-07-10
 */

#include <iostream>
#include <wstring>
#include "flexparser.h"

using namespace std;
using namespace std::tr1;

int basic() {
    shared_ptr<Grammar> g = GrammarFactory.loadFromFile("sample1.cfg");
    shared_ptr<Lexer> lexer = LexerFactory.createLexer(g);
    shared_ptr<Parser> parser = ParserFactory.createCFGParser(g);
    shared_ptr<SyntaxTreeFormatter> formatter = SyntaxTreeFormatterFactory
        .createMergeFormatter();
    
    shared_ptr<vector<wstring>> input = readLinesFromFile("input1.txt", "utf-8");
    shared_ptr<vector<wstring>> refout = readLinesFromFile("parsing1.txt", "utf-8");

    vector<shared_ptr<SyntaxTree>> refTrees;
    for (vector<wstring>::iterator it = refout.begin();
            it != refout.end(); it++ ) {
        refTrees.push_back(formatter.parse(*it));
    }

    int n = input.size();
    bool state = true;
    for (int i = 0; i < n; i++) {
        shared_ptr<Generator<SyntaxTree>> treegen = parser.parse(lexer.lex(input[i]));
        if (treegen->hasNext()) {
            shared_ptr<SyntaxTree> tree = treegen->next();
            if ( *tree == *(refTrees[i])) {
                cout << "No." << i << " OK" << endl;
            } else {
                cout << "No." << i << " fail: " << formatter.format(tree) << " "
                    << formatter.format(refTrees[i]) << endl;
                state = false;
            }
        } else {
            cout << "No." << i << " fail parsing" << endl;
            state = false;
        }
    }
    return state;
}

int main() {
    return basic();
}
